package il.ac.bgu.soa2009.hw6.cinema.impl;

import il.ac.bgu.soa2009.hw6.cinema.*;

/**
 * User: Henry
 * Date: 03/04/2009
 * Time: 17:55:49
 */
public class Cinema {
    private HallContainer[] halls;


    public void setHallsNumber(int num) throws CinemaException {
        synchronized (Cinema.class) {
            if (num < 0) {
                throw new CinemaException("Illegal number of halls!");
            }
            halls = new HallContainer[num];
            for (int i = 0; i < num; i++) {
                halls[i] = new HallContainer(i);
            }
        }
    }

    public void setHallSeats(il.ac.bgu.soa2009.hw6.cinema.Hall[] halls) throws CinemaException {
        if (halls == null) {
            throw new CinemaException("Halls number not set");
        }
        for (il.ac.bgu.soa2009.hw6.cinema.Hall hall : halls) {
            int number = hall.getNumber();
            if (number < 0 || number >= halls.length) {
                throw new HallDoesNotExistException();
            }
            this.halls[number].setSeatsCount(hall.getSeats());
        }
    }

    public void setMovie(MovieInHall movieInHall) throws CinemaException {
        if (halls == null) {
            throw new CinemaException("Halls number not set");
        }
        int hallId = movieInHall.getHall();
        if (hallId < 0 || hallId >= halls.length) {
            throw new HallDoesNotExistException();
        }
        Movie movie = movieInHall.getMovie();
        String newMovieName = movie.getMovieName().trim();
        if ("".equals(newMovieName)) {
            throw new CinemaException("Movie Name must have at least one character!");
        }
        if (getHallIdByMovieName(newMovieName) != -1) {
            throw new MovieAlreadyExistsException("Movie already exists !");
        }
        movie.setMovieName(newMovieName);
        halls[hallId].setMovie(movie);
    }

    private int getHallIdByMovieName(String movieName) throws CinemaException {
        if (halls == null) {
            throw new CinemaException("Halls number not set");
        }
        for (HallContainer hall : halls) {
            Movie movie = hall.getMovie();
            if (movie != null && movie.getMovieName() != null && movie.getMovieName().equalsIgnoreCase(movieName)) {
                return hall.getNumber();
            }
        }
        return -1;
    }

    public Movie[] getMovies() {
        Movie[] res = new Movie[countScreeningMovies()];
        int i = 0;
        for (HallContainer hall : halls) {
            if (hall.isScreening()) {
                res[i] = hall.getMovie();
                i++;
            }
        }
        return res;
    }

    private int countScreeningMovies() {
        int res = 0;
        for (HallContainer hall : halls) {
            if (hall.isScreening()) {
                res++;
            }
        }
        return res;
    }

    public Ticket orderTickets(TicketRequest ticketOrder) throws CinemaException {
        String movieName = ticketOrder.getMovieName().trim();
        if ("".equals(movieName)) {
            throw new  CinemaException("Movie Name must have at least one character!");
        }
        int idByMovieName = getHallIdByMovieName(movieName);
        if (idByMovieName == -1) {
            throw new MovieNotFoundException("Movie not found!");
        }
        return halls[idByMovieName].orderTicket(ticketOrder);
    }

    public void cancelTickets(TicketIdentifier orderId) throws CinemaException {
        int hallNumber = orderId.getHallNumber();
        if (hallNumber < 0 || hallNumber >= halls.length) {
            throw new CinemaException("Illegal hallNumber");
        }
        halls[hallNumber].cancelTicket(orderId.getReservationId());
    }
}
